/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.commons.xml;

import java.io.*;
import java.nio.charset.Charset;

/**
 * @author <a href="mailto:hedyn@foxmail.com">HeDYn</a>
 */
public final class Xmls {

    private Xmls() {
    }

    /**
     * @param xml
     * @param path
     * @return
     */
    public static XmlElement node(XmlElement xml, String path) {
        if (!path.startsWith("/")) {
            path = "/" + path;
        }
        String start = "/" + xml.getName() + "/";
        if (!path.startsWith(start)) {
            return null;
        }
        path = path.replaceFirst(start, "");
        String[] nodes = path.split("/");
        for (String node : nodes) {
            xml = xml.getChild(node);
            if (xml == null) {
                return null;
            }
        }
        return xml;
    }

    /**
     * @param xml
     * @param path
     * @return
     */
    public static String nodeContent(XmlElement xml, String path) {
        xml = node(xml, path);
        if (xml == null) {
            return null;
        }
        return xml.getContent();
    }

    /**
     * @param xml
     * @param path
     * @param name
     * @return
     */
    public static String nodeAttr(XmlElement xml, String path, String name) {
        xml = node(xml, path);
        if (xml == null) {
            return null;
        }
        return xml.getStringAttribute(name);
    }

    /**
     * @param xml
     * @param path
     * @param name
     * @param defaultValue
     * @return
     */
    public static String nodeAttr(XmlElement xml, String path,
                                  String name, String defaultValue) {
        xml = node(xml, path);
        if (xml == null) {
            return null;
        }
        return xml.getStringAttribute(name, defaultValue);
    }

    /**
     * @param xml
     * @return
     */
    public static XmlElement xml(String xml) {
        XmlElement x = new XmlElement();
        x.parseString(xml);
        return x;
    }

    public static XmlElement xml(File xmlFile, Charset charset) throws IOException {
        return xml(xmlFile, charset.name());
    }

    /**
     * @param xmlFile
     * @param charsetName
     * @return
     */
    public static XmlElement xml(File xmlFile, String charsetName) throws IOException {
        InputStream in = null;
        try {
            in = new FileInputStream(xmlFile);
            return xml(in, charsetName);
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

    public static XmlElement xml(InputStream input, Charset charset) throws IOException {
        return xml(input, charset.name());
    }

    public static XmlElement xml(InputStream input, String charsetName) throws IOException {
        InputStreamReader reader;
        try {
            reader = new InputStreamReader(input, charsetName);
            return xml(reader);
        } catch (IOException ex) {
            throw ex;
        }
    }

    public static XmlElement xml(Reader reader) throws IOException {
        XmlElement xml = new XmlElement(true);
        xml.parseFromReader(reader);
        return xml;
    }

    public static void save(XmlElement xml, File xmlFile, Charset charset) throws IOException {
        save(xml, xmlFile, charset.name());
    }

    public static void save(XmlElement xml, File xmlFile, String charsetName) throws IOException {
        Writer writer = null;
        try {
            writer = new OutputStreamWriter(new FileOutputStream(xmlFile), charsetName);
            xml.write(writer, true, 4);
            writer.flush();
        } catch (IOException ex) {
            throw ex;
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }
}